#pragma once
#include "Reactor.hpp"
#include "Sock.hpp"
#include "Service.hpp"
#include "Util.hpp"

int Accepter(Event *evp) //这个参数是监听套接字对应的Event事件结构体指针
{
    std::cout << "有新的链接到来了,就绪的sock是: " << evp->sock << std::endl;
    while(true) //把所有连接都获取上来
    {
        int sock = Sock::Accept(evp->sock);//从监听套接字evp->sock当中获取连接
        if(sock < 0) //连接获取完了
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK){ //并没有读取出错,只是底层没有连接了
				return 0;
			}
            else if (errno == EINTR){ //读取的过程被信号中断了
				continue;
			}
            else{ //获取连接失败
				std::cerr << "accept error" << std::endl;
				return -1;
			}
        }
        std::cout << "Accept success: " << sock << std::endl;
        SetNonBlock(sock);//因为是ET模型->所以要把获取到的新链接的文件描述符设置为非阻塞 
        
        //来到这里,获取链接成功   此时这个文件描述符是普通文件描述符
        //构建EventItem结构
        Event *other_ev = new Event();
        other_ev->sock = sock;
        other_ev->R = evp->R; 
        other_ev->RegisterCallback(Recver, Sender, Errorer);//注册回调方法

        //添加该事件结构体到反应堆-将该套接字及其对应的事件注册到Dispatcher中
        Reactor* R = evp->R;
        R->InsertEvent(other_ev, EPOLLIN|EPOLLET);//这次我们关心读取事件,并且是ET模式
    }
}
